use crate::common::{AppState, Response};
use crate::error::AppError;
use crate::models::chat::Chat;
use crate::vo::chat::{ChatReq, ChatRes, PaginationParams};
use crate::vo::ValidatedJson;
use anyhow::Context;
use axum::extract::State;
use axum::response::IntoResponse;
use serde::Serialize;
use std::sync::Arc;

// 排序方向枚举
#[derive(Debug)]
enum SortDirection {
    Ascending,
    Descending,
}

// 排序字段结构
#[derive(Debug)]
struct SortingField {
    name: String,
    direction: SortDirection,
}

#[derive(Debug, Serialize, Default)]
struct PaginatedResponse<T> {
    items: Vec<T>,
    current_page: u32,
    per_page: u32,
    total_items: i64,
    total_pages: u32,
}

pub async fn add_chat(
    State(app_state): State<Arc<AppState>>,
    ValidatedJson(chat): ValidatedJson<ChatReq>,
) -> Result<impl IntoResponse, AppError> {
    let user = app_state
        .user
        .lock()
        .unwrap()
        .clone()
        .context("user not found")?;
    let mut chat_dto: Chat = chat.try_into()?;
    chat_dto.user_id = user.id as i32;
    app_state.create_chat(chat_dto).await?;
    Ok(Response::ok("abc"))
}

// 解析排序字符串
fn parse_sort_fields(sort_str: Option<&str>) -> Vec<SortingField> {
    // 安全字段白名单
    const SAFE_FIELDS: &[&str] = &["id", "name", "created_at"];

    let mut fields = vec![];

    if let Some(sort_str) = sort_str {
        for field in sort_str.split(',') {
            let (name, direction) = match field.strip_prefix('-') {
                Some(n) => (n, SortDirection::Descending),
                None => (field, SortDirection::Ascending),
            };

            // 使用白名单验证字段名
            if SAFE_FIELDS.contains(&name) {
                fields.push(SortingField {
                    name: name.to_string(),
                    direction,
                });
            }
        }
    }

    // 确保至少有一个排序字段
    if fields.is_empty() {
        fields.push(SortingField {
            name: "id".to_string(),
            direction: SortDirection::Ascending,
        });
    }

    fields
}

pub async fn get_chat_list(
    State(app_state): State<Arc<AppState>>,
    ValidatedJson(pagination): ValidatedJson<PaginationParams>,
) -> Result<impl IntoResponse, AppError> {
    let user_id = app_state.user.lock().unwrap().clone().unwrap().id as i32;
    let page = pagination.page.unwrap_or(1);
    let size = pagination.size.unwrap_or(10).clamp(1, 100); // 限制每页最多100
    let offset = (page - 1) * size;

    let mut query_string = r#"
        SELECT id, name, price, created_at
        FROM products
    "#
    .to_string();

    let sort_fields = parse_sort_fields(None);

    // 添加 ORDER BY 子句
    if !sort_fields.is_empty() {
        query_string.push_str(" ORDER BY ");

        for (i, field) in sort_fields.iter().enumerate() {
            if i > 0 {
                query_string.push_str(", ");
            }

            query_string.push_str(field.name.as_str());

            match field.direction {
                SortDirection::Ascending => query_string.push_str(" ASC"),
                SortDirection::Descending => query_string.push_str(" DESC"),
            }
        }
    }

    // 查询总数
    let total_count: Result<i64, _> =
        sqlx::query_scalar("SELECT COUNT(*) where user_id = ?  FROM chats")
            .bind(user_id)
            .fetch_one(&app_state.pool)
            .await;

    let total_count = match total_count {
        Ok(count) => count,
        Err(e) => return Err(AppError::ChatError(e.to_string())),
    };

    // 计算总页数
    let total_pages = ((total_count as f64) / (size as f64)).ceil() as u32;

    let chat_list = sqlx::query_as("SELECT * FROM chats where user_id = ? LIMIT ?  OFFSET ? ")
        .bind(user_id)
        .bind(size)
        .bind(offset)
        .fetch_all(&app_state.pool)
        .await?;
    let chat_list: Vec<ChatRes> = chat_list
        .into_iter()
        .map(|chat: Chat| chat.into())
        .collect::<Vec<ChatRes>>();

    Ok(Response::ok(PaginatedResponse::<ChatRes> {
        items: chat_list,
        current_page: page,
        per_page: size,
        total_items: total_count as i64,
        total_pages,
    }))
}
